﻿using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Ioc;
using GalaSoft.MvvmLight.Messaging;
using JiveMessenger.Log;
using JiveMessenger.User;
using JiveMessenger.Utilities;
using JmShared;
using System;
using System.ComponentModel;
using System.Security;
using System.Threading.Tasks;
namespace JiveMessenger.ViewModels
{
    /// <summary>
    /// This class contains properties that a View can data bind to.
    /// <para>
    /// See http://www.galasoft.ch/mvvm
    /// </para>
    /// </summary>
    public class ViewModelRegisterUser : ViewModelBaseEx
    {
        private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
        private IClient _currentClient;
        public RelayCommand<string> PasswordChangedCommand { get; set; }
        public RelayCommand<string> RepeatPasswordChangedCommand { get; set; }
        public AutoRelayCommand RegisterUserCommand { get; set; }

        private string _verificationCode;
        public string VerificationCode
        {
            get { return _verificationCode; }
            set
            {
                if (_verificationCode != value)
                {
                    Set(() => VerificationCode, ref _verificationCode, value, true);
                }
            }
        }

        private string _password;
        public string Password
        {
            get { return _password; }
            set
            {
                if (_password != value)
                {
                    Set(() => Password, ref _password, value, true);
                }
            }
        }
        private string _repeatPassword;
        public string RepeatPassword
        {
            get { return _repeatPassword; }
            set
            {
                if (_repeatPassword != value)
                {
                    Set(() => RepeatPassword, ref _repeatPassword, value, true);
                }
            }
        }
        private bool _isRepeatPasswordOK;
        public bool IsRepeatPasswordOK
        {
            get { return _isRepeatPasswordOK; }
            set
            {
                if (_isRepeatPasswordOK != value)
                {
                    Set(() => IsRepeatPasswordOK, ref _isRepeatPasswordOK, value, true);
                }
            }
        }
        private bool _isPasswordOK;
        public bool IsPasswordOK
        {
            get { return _isPasswordOK; }
            set
            {
                if (_isPasswordOK != value)
                {
                    Set(() => IsPasswordOK, ref _isPasswordOK, value, true);
                }
            }
        }


        private bool _success;
        public bool Success
        {
            get { return _success; }
            set
            {
                if (_success != value)
                {
                    Set(() => Success, ref _success, value);
                }
            }
        }

        private bool _verificationSuccess;
        public bool VerificationSuccess
        {
            get { return _verificationSuccess; }
            set
            {
                if (_verificationSuccess != value)
                {
                    Set(() => VerificationSuccess, ref _verificationSuccess, value);
                }
            }
        }


        private string _username;
        public string Username
        {
            get { return _username; }
            set
            {
                if (_username != value)
                {
                    Set(() => Username, ref _username, value, true);
                }
            }
        }
        private string _usernameStatusText;
        public string UsernameStatusText
        {
            get { return _usernameStatusText; }
            set
            {
                if (_usernameStatusText != value)
                {
                    Set(() => UsernameStatusText, ref _usernameStatusText, value);
                }
            }
        }

        private string _passwordStatusText;
        public string PasswordStatusText
        {
            get { return _passwordStatusText; }
            set
            {
                if (_passwordStatusText != value)
                {
                    Set(() => PasswordStatusText, ref _passwordStatusText, value);
                }
            }
        }
        private string _nextButtonText;
        public string NextButtonText
        {
            get { return _nextButtonText; }
            set
            {
                if (_nextButtonText != value)
                {
                    Set(() => NextButtonText, ref _nextButtonText, value);
                }
            }
        }

        private bool _isNextButtonEnabled;
        public bool IsNextButtonEnabled
        {
            get { return _isNextButtonEnabled; }
            set
            {
                if (_isNextButtonEnabled != value)
                {
                    Set(() => IsNextButtonEnabled, ref _isNextButtonEnabled, value, true);
                }
            }
        }

        private bool _isCancelButtonEnabled;
        public bool IsCancelButtonEnabled
        {
            get { return _isCancelButtonEnabled; }
            set
            {
                if (_isCancelButtonEnabled != value)
                {
                    Set(() => IsCancelButtonEnabled, ref _isCancelButtonEnabled, value);
                }
            }
        }

        private string _verificationStatusText;
        public string VerificationStatusText
        {
            get { return _verificationStatusText; }
            set
            {
                if (_verificationStatusText != value)
                {
                    Set(() => VerificationStatusText, ref _verificationStatusText, value);
                }
            }
        }
        private string _repeatPasswordStatusText;
        public string RepeatPasswordStatusText
        {
            get { return _repeatPasswordStatusText; }
            set
            {
                if (_repeatPasswordStatusText != value)
                {
                    Set(() => RepeatPasswordStatusText, ref _repeatPasswordStatusText, value);
                }
            }
        }
        /// <summary>
        /// Initializes a new instance of the ViewModelRegisterWindow class.
        /// </summary>
        public ViewModelRegisterUser(IClient currentClient)
        {
            _currentClient = currentClient;
            PasswordStatusText = "";
            UsernameStatusText = "";
            IsCancelButtonEnabled = true;
            NextButtonText = "Next";
            IsNextButtonEnabled = true;

            this.RegisterUserCommand = new AutoRelayCommand(RegisterUserCommandAction, CanExecuteRegisterUser);
            this.RegisterUserCommand.DependsOn(() => IsNextButtonEnabled);
            this.RegisterUserCommand.DependsOn(() => Username);
            this.RegisterUserCommand.DependsOn(() => IsPasswordOK);
            this.RegisterUserCommand.DependsOn(() => IsRepeatPasswordOK);
            this.RepeatPasswordChangedCommand = new RelayCommand<string>(RepeatPasswordChangedCommandAction);
            this.PasswordChangedCommand = new RelayCommand<string>(PasswordChangedCommandAction);
        }

        private bool CanExecuteRegisterUser()
        {
            return IsNextButtonEnabled && (Username != null && Username.Length > 0) && (IsPasswordOK && IsRepeatPasswordOK);
        }
        private void RepeatPasswordChangedCommandAction(string pw)
        {

            this.RepeatPassword = pw;
            CheckPasswordEquality();
        }
        private void CheckPasswordEquality()
        {
            if (this.RepeatPassword == null || this.Password == null)
                return;
            if (this.RepeatPassword != this.Password)
            {
                this.RepeatPasswordStatusText = "Passwords are not equal";
                this.IsRepeatPasswordOK = false;
            }
            else
            {
                RepeatPasswordStatusText = string.Empty;
                this.IsRepeatPasswordOK = true;
            }

        }
        private void SendVerification(VerifyMail mail)
        {
            Task t = Task.Factory.StartNew(async (vm) =>
               {
                   DatabaseQueryResponse result = await _currentClient.Connection.VerifyEmail((VerifyMail)vm, AppSettings.Instance.ServerSetting, StaticSettings.ServerPort);
                   this.VerificationSuccess = result.Success;
                   this.VerificationStatusText = result.StatusText;
                   if (result.Success == true)
                   {
                       NextButtonText = "Done";
                       IsCancelButtonEnabled = false;
                   }
                   IsNextButtonEnabled = true;
               }, mail);
        }

        private void RegisterUser(RegisterUser reg)
        {
            Task t = Task.Factory.StartNew(async (ru) =>
            {
                DatabaseQueryResponse result = await _currentClient.Connection.RegisterUser((RegisterUser)ru, AppSettings.Instance.ServerSetting, StaticSettings.ServerPort);
                this.Success = result.Success;
                this.UsernameStatusText = result.StatusText;
                if (result.Success == true)
                {
                    NextButtonText = "Next";
                    IsCancelButtonEnabled = true;
                    Logger.Info("User {0} registered successfully", this.Username);
                }
                else
                    Logger.Warn("Registration of user {0} failed", this.Username);
                IsNextButtonEnabled = true;
            }, reg);
        }


        private void PasswordChangedCommandAction(string pw)
        {
            if (pw.Length >= 0 && pw.Length < 5)
            {
                PasswordStatusText = "Passwords must be at least 5 characters long";
                IsPasswordOK = false;
            }
            else
            {
                PasswordStatusText = string.Empty;
                IsPasswordOK = true;
            }
            this.Password = pw;
        }

        private void RegisterUserCommandAction()
        {
            this.VerificationStatusText = string.Empty;
            this.PasswordStatusText = string.Empty;
            this.UsernameStatusText = string.Empty;
            IsNextButtonEnabled = false;
            if (Success && _verificationSuccess)
            {
                Messenger.Default.Send(new NotificationMessage(this, "CloseWindow"));
                return;
            }
            else if (Success)
            {
                VerifyMail vm = new VerifyMail(this.Username, this.VerificationCode);
                SendVerification(vm);
            }
            else
            {
                RegisterUser reg = new RegisterUser(this.Username, this.Password);
                RegisterUser(reg);
            }

        }

    
        public override void Cleanup()
        {
            SimpleIoc.Default.Unregister<ViewModelRegisterUser>(VmHelper.Locator.ViewModelRegisterWindowKey);
            VmHelper.Locator.ViewModelRegisterWindowKey = System.Guid.NewGuid().ToString();
            base.Cleanup();
        }
    }
}